using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;
using System.Linq;
using UnityEngine;
using UnityEngine.Tilemaps;
using 凌依.工具库.随机工具;

/// <summary>
/// 物品最高父级
/// </summary>
[System.Serializable]
public class 物品数据
{
    public string 名称;
    public string 类型;
    public string 描述;
    public Color 叠加补色;

    public static bool operator ==(物品数据 a, 物品数据 b)
    {
        if (b as object == null && a as object == null)
            return true;
        else if (b as object == null || a as object == null)
            return false;

            return a.名称 == b.名称;
    }
    public static bool operator !=(物品数据 a, 物品数据 b) => !(a == b);

    public override bool Equals(object obj)
    {
        return base.Equals(obj);
    }

    public bool Equals(物品数据 obj)
    {
        return obj.名称 == 名称;
    }

    public override int GetHashCode()
    {
        return base.GetHashCode();
    }

    public T 克隆<T>() where T : 物品数据
    {
        return JsonUtility.FromJson<T>(JsonUtility.ToJson(this));
    }
}
public enum 图层
{
    底层,中层,上层,顶层,全部
}

[System.Serializable]
public class 掉落数据
{
    public string 道具;
    public int 最小数量;
    public int 最大数量;
    public 掉落数据(string 道具, int 最小数量, int 最大数量)
    {
        this.道具 = 道具;
        this.最小数量 = 最小数量;
        this.最大数量 = 最大数量;
    }
    public 掉落数据()
    {

    }
}

[System.Serializable]
public class 道具模板 : 物品数据
{
    public bool 不可更改 = true;
    public 品质 品质;
    public int 价值;
    public int 质量;
    public T 克隆模板<T>() where T : 道具模板
    {
        T 返回 = this.克隆<T>();
        返回.不可更改 = false;
        return 返回;
    }
}

[System.Serializable]
public class 地图物品模板 : 物品数据
{
    public bool 不可更改 = true;
    public Vector2Int 所在位置 = new Vector2Int(-1, -1);
    public T 克隆模板<T>(Vector2Int 瓦片pos) where T : 地图物品模板
    {
        T 返回 = this.克隆<T>();
        返回.所在位置 = 瓦片pos;
        返回.不可更改 = false;
        return 返回;
    }
}
[System.Serializable]
public class 地图物品 : 地图物品模板
{
    public TileBase 瓦片;
    public int 耐久;
    public string 材质;
    public List<掉落数据> 掉落信息 = new List<掉落数据>();
    public 图层 图层;
}
[System.Serializable]
public class 道具物品 : 道具模板
{
    public Sprite 贴图;
    public string 材质;
    public int 数量;
    public int 叠加上限;
}
[System.Serializable]
public class 植物 : 地图物品模板
{
    public List<Sprite> 贴图 = new List<Sprite>();
    public int 耐久;
    public List<掉落数据> 掉落信息 = new List<掉落数据>();
    public int 生长周期;
    public float 生长进度 = 0;
}

[System.Serializable]
public class 色彩信息_渐变 : 色彩信息
{
    public Color 结束色;

    public 色彩信息_渐变(string 名称, Color 起始色, Color 结束色)
    {
        this.名称 = 名称;
        this.色彩 = 起始色;
        this.结束色 = 结束色;
    }

    public 色彩信息_渐变()
    {

    }

    public Color 获取随机区间值()
    {
        return Color.Lerp(色彩, 结束色, Random.value);
    }
}

/// <summary>
/// 关于色彩的父级
/// </summary>
[System.Serializable]
public class 色彩信息
{
    public string 名称;
    public string 类型;
    public Color 色彩;
}

[System.Serializable]
public class 色彩信息_集合 : 色彩信息
{
    public List<Color> 预制色彩 = new List<Color>();
    public Color 随机获取()
    {
        return 预制色彩[Random.Range(0, 预制色彩.Count - 1)];
    }
}

[System.Serializable]
public class 器官集合
{
    public List<器官信息> 器官 = new List<器官信息>();
    public int 基因基准值;
    public int 基准值序号;

    public void 查找基准值序号()
    {
        for (int i = 0; i < 器官.Count; i++)
        {
            if (器官[i].基因优越度 == 基因基准值)
            {
                基准值序号 = i;
                return;
            }
        }
    }
}

[System.Serializable]
public class 种族信息
{
    public string 种族名称;
    public int 基因优越度;
    public 色彩信息_渐变 皮肤色;
    public 色彩信息_渐变 发型色;
    public 角色装备 肉体;

    public Dictionary<string, 器官集合> 器官信息集合 = new Dictionary<string, 器官集合>();

    public List<人形生物贴图> 面部 = new List<人形生物贴图>();
    public List<人形生物贴图> 发型 = new List<人形生物贴图>();

    private List<人形生物贴图> 面部_N = new List<人形生物贴图>();
    private List<人形生物贴图> 面部_V = new List<人形生物贴图>();
    private List<人形生物贴图> 发型_N = new List<人形生物贴图>();
    private List<人形生物贴图> 发型_V = new List<人形生物贴图>();

    public List<增益信息> 种族特殊效果 = new List<增益信息>();

    public static List<string> 获取贴图名称(List<人形生物贴图> 对象)
    {
        List<string> vs = new List<string>();
        if (对象 == null)
            return null;
        foreach (var item in 对象)
            vs.Add(item.名称);

        return vs;
    }

    public void 添加器官(器官信息 器官,int 基准值)
    {
        string 类型 = 器官.器官类型;
        if (!器官信息集合.ContainsKey(类型))
        {
            器官集合 添加 = new 器官集合();
            添加.基因基准值 = 基准值;
            添加.器官.Add(器官);

            器官信息集合.Add(类型, 添加);
        }

        器官信息集合[类型].器官.Add(器官);

        器官信息集合[类型].器官 = 器官信息集合[类型].器官.OrderBy((t) => t.基因优越度).ToList();
        器官信息集合[类型].查找基准值序号();
    }

    public 器官信息 随机获取器官(string 类型)
    {
        器官集合 集合 = 器官信息集合[类型];
        if (Random.Range(0, 100) >= 95)
        {
            if(Random.Range(0, 2) == 1 )//天才
                return 集合.器官[Random.Range(集合.基准值序号, 集合.器官.Count)].克隆<器官信息>();
            else
                return 集合.器官[Random.Range(0,集合.基准值序号)].克隆<器官信息>();
        }
        else
            return 集合.器官[集合.基准值序号].克隆<器官信息>();
    }

    private void 检测()
    {
        if(面部_N.Count == 0)
            初始化();
    }

    private 人形生物贴图 随机获取(List<人形生物贴图> 组)
    {
        检测();
        return 随机.随机选择(组);
    }

    public void 获取贴图(out List<人形生物贴图> 发型, out List<人形生物贴图> 面部,string 性别)
    {
        检测();
        if (性别 == "男")
        {
            发型 = 发型_N;
            面部 = 面部_N;
        }
        else
        {
            发型 = 发型_V;
            面部 = 面部_V;
        }
    }

    public 人形生物贴图 随机获取男性发型() => 随机获取(发型_N);

    public 人形生物贴图 随机获取女性发型() => 随机获取(发型_V);

    public 人形生物贴图 随机获取男性面部() => 随机获取(面部_N);

    public 人形生物贴图 随机获取女性面部() => 随机获取(面部_V);


    public void 初始化()
    {
        foreach (var item in 面部)
        {
            if (item == null)
                continue;
            if (item.性别 == "男")
                面部_N.Add(item);
            else if (item.性别 == "女")
                面部_V.Add(item);
        }

        foreach (var item in 发型)
        {
            if (item == null)
                continue;
            if (item.性别 == "男")
                发型_N.Add(item);
            else if(item.性别 == "女")
                发型_V.Add(item);
        }
    }


}